package com.ifast.face.service.impl;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ifast.api.util.JWTUtil;
import com.ifast.common.config.IFastConfig;
import com.ifast.common.utils.MD5Utils;
import com.ifast.common.utils.Result;
import com.ifast.face.dao.CameraDao;
import com.ifast.face.domain.Camera;
import com.ifast.face.service.CameraService;
import com.ifast.face.service.FaceEngineService;
import com.ifast.face.service.run.RtmpTurnRun;
import com.ifast.face.util.WorkId;

import cn.hutool.core.util.ReflectUtil;


@Service
public class CameraServiceImpl extends ServiceImpl<CameraDao, Camera> implements CameraService {
	
	@Autowired
	private FaceEngineService faceEngineService; 
	private static ConcurrentHashMap<Long,RtmpTurnRun> threadMap = new ConcurrentHashMap<Long,RtmpTurnRun>();
	
	private static ExecutorService executor = Executors.newCachedThreadPool();
	@Value("${pushKey}")
	private String pushKey;
	@Value("${pushSecret}")
	private String pushSecret;
	@Autowired
	private IFastConfig conf;
	
	@Override
	public Result<?> push(String id,String userId){
		Camera camera = baseMapper.selectById(id);
		if(camera == null || StringUtils.isBlank(camera.getFetchUrl())){
			return Result.fail("缺少视频源");
		}
		if(StringUtils.isBlank(camera.getPushUrl())){
			return Result.fail("缺少推送地址");
		}
		if(StringUtils.isBlank(camera.getGroupType())){
			return Result.fail("请选择摄像头分组");
		} 
		if(threadMap.containsKey(camera.getId())){
			return Result.fail("视频正在推送中，请先取消推送");
		}
		try { 
			String appName = WorkId.sortUID();
			String token = JWTUtil.sign(userId,userId,conf.getJwt().getExpireTime());
			//发布token
			String push = "?token="+MD5Utils.encrypt(pushKey,pushSecret)+"/"+appName;
			//播放token
			String get =  "?token="+token+"/"+appName;
			String pushUrl = camera.getPushUrl()+push;
			String getUrl = camera.getPushUrl()+get; 
			threadMap.put(camera.getId(),doPush(camera.getFetchUrl(),pushUrl,camera.getGroupType()));
			camera.setStatus(1);
			camera.setRtmpUrl(getUrl);
			baseMapper.updateById(camera);
			return Result.ok();
		} catch (Exception e) {
			camera.setStatus(2);
			baseMapper.updateById(camera);
			return Result.fail("推送失败"); 
		}
	}
	
	private RtmpTurnRun doPush(String fetchUrl,String pushUrl,String groupName){ 
		RtmpTurnRun rtmpRun = new RtmpTurnRun(faceEngineService,fetchUrl,pushUrl,groupName);
		executor.execute(rtmpRun);
		return rtmpRun;
	}
	
	@Override
	public Result<?> endPush(String id){
		Camera camera = baseMapper.selectById(id);
		if(camera == null){
			return Result.fail("没有当前视频源");
		}
		if(threadMap.containsKey(camera.getId())){
			RtmpTurnRun rtmpRun = threadMap.get(camera.getId());
			ReflectUtil.setFieldValue(rtmpRun, "stop", false);
			threadMap.remove(camera.getId());
			camera.setStatus(0);
			camera.setRtmpUrl("");
			baseMapper.updateById(camera);
		} 
		return Result.ok();
	}
	@Override
	public List<Camera> getMapCameraByFourCorners(String minX, String minY, String maxX, String maxY) {
		return baseMapper.selectList(new QueryWrapper<Camera>().between("LAT", minX, maxX).between("LNG", minY, maxY));
	}
}
